/********************************************************
파일명 : Template.java
작성일자 : 2012-02-28
수정일자 : 
작성자 : 
수정자 : 
작성 내용 : HTML파일을 읽어서 화면에 보여주기 위한 작업
수정 내용 : 
*********************************************************/


/***********************************************
 *
 * 함수 리스트
 * getFileTop			: One Frame일 경우 TOP화면 정보
 * getFileLeft			: One Frame일 경우 LEFT화면 정보
 * getFileBottom		: One Frame일 경우 BUTTOM화면 정보
 * setFiletop			: TOP화면의 HTML을 읽어들인다.(NIO 사용)
 * setFileleft			: LEFT화면의 HTML을 읽어들인다.(NIO 사용)
 * setFilebottom		: BOTTOM화면의 HTML을 읽어들인다.(NIO 사용)
 * setFileText			: 파일을 읽어 특정변수를 변경한다.(NIO 사용)
 * getFileText			: 파일의 내용을 리턴한다.
 * setLoopText			: 루프를 돌면서 데이터를 변경한다.
 * getLoopText			: 시작문자열과 종료문자열이 없는 Text를 리턴
 * getLoopTextInclude	: 시작문자열과 종료문자열이 포함된 Text를 리턴
 * getReplaceText		: 문자열 strSrc에서 문자열 oldStr의 값을 newStr로 바꾼후 리턴
 * getHashTable			: HashTable객체를 return
 * setReplaceKey		: strFileTextVT에서 단일 변수를 변환한다
 * setLoopVariable		: HashTable hT 에 설정된 루프 변수를 멤버 변수 vector vt에 설정한다
 * setReplaceLoopText	: 파일 내용이 저장된 멤버 변수 strFileTextVT에서 루프 변수를 변환한다
 * getVectorElements	: 멤버변수 vector vt의 내용을 출력하는 확인용 함수
 * getVar				: 디버깅용 함수
 * printErr				: 에러출력용 함수
 *
 **********************************************/
package com.ubst.smartad.template;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;


public class Template {

	private 	String strFileText;
	private 	String strFiletop ="";
	private 	String strFileleft ="";
	private 	String strFilebottom ="";
	private 	String strLoopText;
	private 	String strLoopTextInclude;

	private 	String strFileTextVT;
	private 	Vector vt;
	private  	Hashtable hT = new Hashtable();

	/**
	 * 생성자 벡터를 초기화 한다.
	 */
	public Template () {
		vt = new Vector();
	}

	public String getFileTop() { return this.strFiletop; }
	public String getFileLeft() { return this.strFileleft; }
	public String getFileBottom() { return this.strFilebottom; }

	/**
	 * 파일의 내용을 모두 읽어 멤버변수 strFileText와 strFileTextVT 변수에 파일의 내용을
	 * 모두  저장합니다.
	 * 속도 개선을 목적으로 NIO Class를 사용하였습니다
	 *
	 * @param 	filename 경로 + 파일 이름
	 * @exception IOException 해당경로의 파일을 찾을 수 없을때 예외 발생
	 * @return void
	 * @version 1.0
	 */
	public void setFiletop(String filename) throws IOException {
		FileReader f = new FileReader(filename);
		BufferedReader in = null;
		StringBuffer sb = null;
		char c;
		int  i;

		sb = new StringBuffer();
		try {
			in = new BufferedReader(f);
			for(String line; (line=in.readLine()) != null; ) {
				sb.append(line).append("\n");
			}
			strFiletop = sb.toString();
			// 반환 합니다.
			sb = null;

		} catch (FileNotFoundException e) {
			throw e;
		}finally{
			if(in!=null){
				try{in.close();}catch(Exception ee){}
			}
			if(f!=null){
				try{f.close();}catch(Exception ee){}
			}
		}
	}

	/**
	 * 파일의 내용을 모두 읽어 멤버변수 strFileText와 strFileTextVT 변수에 파일의 내용을
	 * 모두  저장합니다.
	 *
	 * @param 	filename 경로 + 파일 이름
	 * @exception IOException 해당경로의 파일을 찾을 수 없을때 예외 발생
	 * @return void
	 * @version 1.0
	 */
	public void setFileleft(String filename) throws IOException {
		FileReader f = new FileReader(filename);
		BufferedReader in = null;
		StringBuffer sb = null;
		char c;
		int  i;

		sb = new StringBuffer();
		try {
			in = new BufferedReader(f);
			for(String line; (line=in.readLine()) != null; ) {
				sb.append(line).append("\n");
			}
			strFileleft = sb.toString();
			// 반환 합니다.
			sb = null;

		} catch (FileNotFoundException e) {
			throw e;
		}finally{
			if(in!=null){
				try{in.close();}catch(Exception ee){}
			}
			if(f!=null){
				try{f.close();}catch(Exception ee){}
			}
		}
	}

	/**
	 * 파일의 내용을 모두 읽어 멤버변수 strFileText와 strFileTextVT 변수에 파일의 내용을
	 * 모두  저장합니다.
	 *
	 * @param 	filename 경로 + 파일 이름
	 * @exception IOException 해당경로의 파일을 찾을 수 없을때 예외 발생
	 * @return void
	 * @version 1.0
	 */
	public void setFilebottom(String filename) throws IOException {
		FileReader f = new FileReader(filename);
		BufferedReader in = null;
		StringBuffer sb = null;
		char c;
		int  i;

		sb = new StringBuffer();
		try {
			in = new BufferedReader(f);
			String line = null;
			while((line=in.readLine()) != null ) {
				sb.append(line).append("\n");
			}

			strFilebottom = sb.toString();
			// 반환 합니다.
			sb = null;

		} catch (FileNotFoundException e) {
			throw e;
		}finally{
			if(in!=null){
				try{in.close();}catch(Exception ee){}
			}
			if(f!=null){
				try{f.close();}catch(Exception ee){}
			}
		}
	}

	/**
	 * 파일의 내용을 모두 읽어 멤버변수 strFileText와 strFileTextVT 변수에 파일의 내용을
	 * 모두  저장합니다.
	 *
	 * @param 	filename 경로 + 파일 이름
	 * @exception IOException 해당경로의 파일을 찾을 수 없을때 예외 발생
	 * @return void
	 * @version 1.0
	 */
	public void setFileText(String filename) throws IOException {
		FileReader f = new FileReader(filename);
		BufferedReader in = null;
		StringBuffer sb = null;
		char c;
		int  i;

		sb = new StringBuffer();
		try {
			in = new BufferedReader(f);
			for(String line; (line=in.readLine()) != null; ) {
				sb.append(line).append("\n");
			}

			strFileText = sb.toString();
			strFileTextVT = strFileText;
			// 반환 합니다.
			sb = null;

			setReplaceKey("{TOP}", ""+ strFiletop);
			setReplaceKey("{LEFT}", ""+ strFileleft);
			setReplaceKey("{BOTTOM}", ""+ strFilebottom);
		} catch (FileNotFoundException e) {
			throw e;
		}finally{
			if(in!=null){
				try{in.close();}catch(Exception ee){}
			}
			if(f!=null){
				try{f.close();}catch(Exception ee){}
			}
		}
	}


	/**
	 * 멤버변수 strFileTextVT를 반환합니다.
	 *
	 * @param strType 템풀릿 종류를 선택할 수 있는 플래그 vt값을 넣어주면 벡터형식의 템플릿을 이용한다.
	 * @return String 값의 형태로 파일을 리턴한다.
	 * @version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////
	//	화일의 내용을 리턴합니다
	////////////////////////////////////////////////////////////////////////////////////
	public String getFileText(String strType) {
		if(strType==null || !strType.equals("vt")){
			return strFileText;
		}else{
			return strFileTextVT;
		}
	}


	/**
	 *  읽어 들인 파일의 내용에서 strStart문자열부터 strEnd문자열까지의 내용을 멤버변수 strLoopTextInclude에 저장 
	 *	strStart문자열의 끝부분부터 strEnd문자열의 처음까지를 strLoopText에 저장  
	 * 	함수 setFileText()를 먼저 호출해야 함. 
	 *
	 * @param strStart filename에서 텍스트 strStart를 찾는다. 
	 * @param strEnd filename에서 테스트 strEnd를 찾는다.
	 * @return void
	 * @version 1.1
	 */
	////////////////////////////////////////////////////////////////////////////////////
	// 	3-1. a. 문자열 strStart 다음 문자열 부터 문자열 strEnd 이전 문자열까지 멤버 변수 strLoopText에 저장
	//		 b. 문자열 strStart 부터 strEnd 문자열까지 멤버변수 strLoopTextInclude에 저장	
	////////////////////////////////////////////////////////////////////////////////////
	public void setLoopText(String strStart, String strEnd) {

		String strTmp ;
		int iPosStart;
		int iPosEnd;

		strTmp = getFileText(null);

		try { 

			if ( ((iPosStart = strTmp.indexOf(strStart,0)) != -1) && ((iPosEnd = strTmp.indexOf(strEnd,0)) != -1 ) ) {
				strLoopTextInclude = strTmp.substring( iPosStart , iPosEnd + strEnd.length());
				strLoopText = strTmp.substring( iPosStart + strStart.length(), iPosEnd - 1 );  
			}

		} catch ( Exception e ) {
			//System.out.println ("[ Function Name : setLoopText ] " +  e );
		}
	}


	/**
	 * 멤버변수 strLoopText를 반환합니다.
	 */
	////////////////////////////////////////////////////////////////////////////////////
	//	4. 시작문자열과 종료문자열이 없는 Text를 리턴 //  
	////////////////////////////////////////////////////////////////////////////////////
	public String getLoopText() {
		return strLoopText;
	}


	/**
	 * 멤버변수 strLoopTextInclude를 반환합니다.
	 */
	////////////////////////////////////////////////////////////////////////////////////
	//	5. 시작문자열과 종료문자열이 포함된 Text를 리턴
	////////////////////////////////////////////////////////////////////////////////////
	public String getLoopTextInclude(){
		return strLoopTextInclude;
	}



	/**
	 *  String strSrc의 내용중에 strOld의 문자열을 strNew문자열로 replace 
	 *
	 * @param strSrc 원본 문자열 
	 * @param strOld 치환될 문자열
	 * @param strNew 새로 치환되는 문자열
	 * @version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////
	//	6. 문자열 strSrc에서 문자열 oldStr의 값을 newStr로 바꾼후 리턴 
	////////////////////////////////////////////////////////////////////////////////////
	public String getReplaceText(String strSrc, String strOld, String strNew) {

		if ( strSrc == null ) return "null";
		if ( strNew == null ) strNew = "";

		int iLen = strSrc.length() + (strNew.length() - strOld.length()) * ( strSrc.length() / strOld.length());
		StringBuffer strFront = new StringBuffer();
		StringBuffer strTemp = new StringBuffer();

		int iPos = 0;
		int iIndex = 0;

		try {
			while ( ( iPos = strSrc.indexOf ( strOld , iIndex) ) != -1 ) {

				strFront.append(strSrc.substring(iIndex, iPos )).append(strNew);

				iIndex = iPos + strOld.length();
			}
			strFront.append(strSrc.substring(iIndex));

		} catch ( Exception e ) {
			//System.out.println ("[ Function Name : getRePlaceText ] " + e );
		}
		
		return strFront.toString();
	}


	/**
	 *	멤버 변수인 hT의 인스턴스를 반환합니다.
	 * 	@version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////////////////
	//	21. HashTable객체를 return 합니다.
	////////////////////////////////////////////////////////////////////////////////////////////////
	public Hashtable getHashTable() {
		return hT;
	}


	/**
	 *  파일 내용이 저장된 멤버 변수 strFileTextVT에서 strKey문자열을 strValue 문자열로 replace 
	 * 	@param strKey 변수 이름
	 *  @param strValue 변수 값 
	 * 	@version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////////////////
	//  22. strFileTextVT에서 단일 변수를 변환한다.
	////////////////////////////////////////////////////////////////////////////////////////////////
	public void setReplaceKey(String strKey, String strValue) {

		if ( strValue == null ) {
	 		strValue="";
		}
		int iPos, iSPos, iEPos;

		StringBuffer strTemp = new StringBuffer(strFileTextVT);

		try {
			while ((iSPos = strTemp.indexOf(strKey)) != -1) { // strFileTextVT에 strKey가 있는지 찾는다.
				iSPos = strTemp.indexOf(strKey); // 변수의 시작 위치를 구한다.
				iEPos = iSPos + strKey.length(); // 변수의 끝위치를 구한다.
				strTemp = strTemp.replace(iSPos, iEPos, strValue); // strKey의 부분을 strValue로 replace 
			}
			strFileTextVT = strTemp.toString();

		} catch ( Exception e ) {
			e.printStackTrace();
		}
	}
	

	/**
	 * 	HashTable hT 에 설정된 루프 변수를 멤버 변수 vector vt에 등록한다. ==> setting 한다.
	 * 	@param strLoopName 루프 변수의 이름
	 * 	@version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////////////////
	// 	23. HashTable hT 에 설정된 루프 변수를 멤버 변수 vector vt에 등록한다. ==> setting 한다.
	////////////////////////////////////////////////////////////////////////////////////////////////
	public void setLoopVariable(String strLoopName) {
		Hashtable hs = new Hashtable();
		hs.put(strLoopName, new Hashtable(hT));
		////////////////////////////////////////////////////////////////////////////////////////////////
		//	vector의 키로 loop의 이름을...  // value로 해시 테이블을 설정
		////////////////////////////////////////////////////////////////////////////////////////////////
		vt.addElement(hs); 

		hT.clear();
	}

	/**
	 * 	파일 내용이 저장된 멤버 변수 strFileTextVT에서 루프 변수를 실제 데이터로 변환 한다.  
	 * 	@param strKey 루프 변수의 이름
	 * 	@version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////////////////
	// 	24. 파일 내용이 저장된 멤버 변수 strFileTextVT에서 루프 변수를 변환한다.
	////////////////////////////////////////////////////////////////////////////////////////////////
	public void setReplaceLoopText(String strKey) {


		String strStart     = "<LOOP NAME=\"" + strKey.toUpperCase() + "\">";
		String strEnd       = "</LOOP NAME=\"" + strKey.toUpperCase() + "\">";
		String strLoop = "";
		int	iSPos, iEPos    = 0;
		int iStart          = strFileTextVT.toUpperCase().indexOf(strStart) + strStart.length(); 	//	Loop의 시작 위치를 저장
		int iEnd            = strFileTextVT.toUpperCase().indexOf(strEnd); 	// Loop의 끝위치를 저장

		int i = 0;
		
		if(iStart== -1|| iEnd == -1 ){
			return;
		}
		strLoop = strFileTextVT.substring(iStart, iEnd); // Loop를 돌아야 할 내용만 가져옵니다.

		//String strTemp      = null;
		//String strTempAll   = "";
		StringBuffer strTemp      = new StringBuffer();
		StringBuffer strTempAll   = new StringBuffer();
		String strTempKey   = null;
		String strTempValue = null;

		try {

			for ( i = 0 ; i < vt.size() ; i++ ) { // 벡터의 사이트 만큼
				Hashtable hsTemp  = (Hashtable)vt.elementAt(i); // vector에 저장 되어 있는 hashTable 변수를 가져옵니다.
				if ( hsTemp.containsKey(new String(strKey) ) ) { // hashTable에 loop이름이 키값으로 있는지 확인합니다. 
					Hashtable hs  = (Hashtable)hsTemp.get(strKey);
					strTemp= new StringBuffer(strLoop);   // Loop부분을 초기화 합니다.
					Enumeration e = hs.keys(); // hashTable의 키들에 대한 enumeration 객체를 구합니다. 
					while(e.hasMoreElements()) {  // enumeration 객체의 멤버가 있다면
						strTempKey   = (String)e.nextElement(); 	// enumeration에서 변수의 이름을 가져옵니다.
						strTempValue = (String)hs.get(strTempKey); // hashTable에서 변수에 해당하는 값을 가져옵니다.
						while ((iSPos = strTemp.indexOf(strTempKey)) != -1) { // 변수의 이름이 반복문 안에 있으면 
							iSPos = strTemp.indexOf(strTempKey); // 변수값의 시작 위치를 구합니다.
							iEPos = iSPos + strTempKey.length(); // 변수값의 끝위치를 구합니다. 
							strTemp = strTemp.replace(iSPos,iEPos,strTempValue); // 변수의 이름과 변수의 값을 replace합니다.
						}
					}
					strTempAll.append(strTemp); // replace된 row를 저장합니다.
				}
			}
			strFileTextVT= new StringBuffer(strFileTextVT).replace(iStart-strStart.length(), iEnd+strEnd.length(), strTempAll.toString() ).toString();
		}  catch ( Exception e ) {
			e.printStackTrace();
		}
	}

	/**
	 * 	파일 내용이 저장된 멤버 변수 strFileTextVT에서 루프 변수를 실제 데이터로 변환 한다.  
	 * 	@param strKey 루프 변수의 이름
	 *	@param opt	"none"  이면 setReplaceLoopText(strKey)를 call합니다..
	 * 	@version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////////////////
	// 	24. 파일 내용이 저장된 멤버 변수 strFileTextVT에서 루프 변수를 변환한다.
	////////////////////////////////////////////////////////////////////////////////////////////////
	public void setReplaceLoopText(String strKey, String opt ) {

		String strStart     = "<LOOP NAME=\"" + strKey.toUpperCase() + "\">";
		String strEnd       = "</LOOP NAME=\"" + strKey.toUpperCase() + "\">";
		int	iSPos, iEPos    = 0;

		if ( opt.equals("none" ) ) {
			int iStart          = strFileTextVT.toUpperCase().indexOf(strStart); 	//	Loop의 시작 위치를 저장
			int iEnd            = strFileTextVT.toUpperCase().indexOf(strEnd) + strEnd.length(); 	// Loop의 끝위치를 저장
			String strLoop      = strFileTextVT.substring(iStart, iEnd); // Loop를 돌아야 할 내용만 가져옵니다.
			strFileTextVT = getReplaceText(strFileTextVT,strLoop,"");	// 파일에서 loop text를 replace합니다.
		} else {

			setReplaceLoopText(strKey); // 옵션값이 none이 아니면 원래의 함수를 call합니다.
		}
	}

	/**
	 * 	멤버 변수 vector vt의 내용을 출력하는 확인용 함수 
	 * 	@version 1.0
	 */
	////////////////////////////////////////////////////////////////////////////////////////////////
	// 	25. 멤버변수 vector vt의 내용을 출력하는 확인용 함수 
	////////////////////////////////////////////////////////////////////////////////////////////////
	public String getVectorElements() {

		StringBuffer 	strTemp = new StringBuffer();
		String 	strKey = "";
		int		i = 0 ;

		Enumeration e = vt.elements();

		while ( e.hasMoreElements() ) {
			strKey = e.nextElement() + " : ";
			strTemp.append(String.valueOf(i)).append(" order key  == > >").append(strKey).append("< ||||| value == > >").append(vt.get(i)).append("<br>"); 
			i++;
		}
		return strTemp.toString();
	}

	////////////////////////////////////////////////////////////////////////////////////
	//	16.	String 형 변수의 이름을 문자열로 받고 - strVarName 
	//		String 형 변수의 값을 받아 - strVarValue 
	//		화면에 출력하는 디버깅용 함수 ;
	////////////////////////////////////////////////////////////////////////////////////
	//		getVar(strFileName,"strFileName");
	////////////////////////////////////////////////////////////////////////////////////
  	public String getVar(String strVarValue, String strVarName) {
  		StringBuffer strTemp = new StringBuffer();
		strTemp.append("<table border=1 bordercolorlight=black bordercolordark=white cellpadding=3 cellspacing=0 style=\"font-size=9pt\" align=center width=600>\n")
			.append("<tr bgcolor=gray><td width=30%>변수이름 </td><td bgcolor=gray>변수값</td></tr>\n")
			.append("<tr bgcolor=darkgray><td>").append(strVarName).append("</td><td bgcolor=darkgray>").append(strVarValue).append("</td></tr></table><br>\n");
		return strTemp.toString(); 
  	}

	////////////////////////////////////////////////////////////////////////////////////
	//	17.	Int 형 변수의 이름을 문자열로 받고 - strVarName 
	//		Int 형 변수의 값을 받아 - iVarValue 
	//		화면에 출력하는 디버깅용 함수 ;
	////////////////////////////////////////////////////////////////////////////////////
	//		getVar(iTotalRow,"iTotalRow");
	////////////////////////////////////////////////////////////////////////////////////
  	public String getVar(int iVarValue, String strVarName) {
  		StringBuffer strTemp = new StringBuffer();
		strTemp.append("<table border=1 bordercolorlight=black bordercolordark=white cellpadding=3 cellspacing=0 style=\"font-size=9pt\" align=center width=600>\n")
			.append("<tr bgcolor=gray><td width=30%>변수이름 </td><td bgcolor=gray>변수값</td></tr>\n")
			.append("<tr bgcolor=darkgray><td>").append(strVarName).append("</td><td bgcolor=darkgray>").append(String.valueOf(iVarValue)).append("</td></tr></table><br>\n");
		return strTemp.toString(); 
  	}

	/**
	  * 에러 메세지를 출력합니다.
	  * @param msg 에러메세지
	  * @return String
	  */

	public String printErr(String msg) {
		StringBuffer sbTemp = new StringBuffer();
		sbTemp.append("<table border=1 bordercolorlight=black bordercolordark=white ");
		sbTemp.append(" cellpadding=3 cellspacing=0 style=\"font-size=9pt\" align=center width=600>\n");
		sbTemp.append(" <tr bgcolor=gray><td width=30% align=center>오류 메세지</td></tr>\n");
		sbTemp.append(" <tr bgcolor=darkgray><td align=center>").append(msg).append("</td></tr></table><br>\n");
		return sbTemp.toString(); 
	}


}
